//===============================
//  功能 ：备注 
//  作者 ：上中野辅亚瑟王 
//  创建时间 ：2023-05-30  15-34-11 
//  Unity版本  ：2019.4.35f1 
//  变更时间 :  2023-05-30  15-34-11 
//===============================





using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace ZS.U3D.BASE.Runtime.Singleton
{
    public class SingletonManager
    {
        private class Wrapper 
        { 
            public int Priority { private set; get; }

            public ISingleton Singleton { private set; get; }

            public Wrapper(ISingleton singleton,int priority) {
                Singleton = singleton;
                Priority = priority;
            }
        }

        private static bool _isInitialize = false;
        private static GameObject _driver = null;
        public static GameObject Driver { get { return _driver; } }
        private static readonly List<Wrapper> _wrappers = new List<Wrapper>();
        private static MonoBehaviour _behaviour;
        private static bool _isDirty = false;

        /// <summary>
        /// 初始化单例系统
        /// </summary>
        public static void Initialize() 
        {
            if (_isInitialize)
            {
                MyDebug.LogWarning($"{nameof(SingletonManager)} is Initialized ");
                return;
            }
            {
                _isInitialize = true;
                _driver = new GameObject($"[{nameof(SingletonManager)}]");
                _behaviour = _driver.AddComponent<SingletonDriver>();
                Object.DontDestroyOnLoad(_driver);
                MyDebug.Log($"{nameof(SingletonManager)} is initalize !");
            }
        }

        /// <summary>
        /// 销毁单例系统
        /// </summary>
        public static void Destroy() {
            if (_isInitialize)
            {
                DestroyAll();

                _isInitialize = false;
                if (_driver!=null)
                {
                    Object.Destroy(_driver);
                }
                MyDebug.Log($"{nameof(SingletonManager)} destroy all !");
            }
        }

        internal static void Update() {
            if (_isDirty)
            {
                _isDirty = false;
                _wrappers.Sort((left, right) => 
                {
                    if (left.Priority>right.Priority)
                    {
                        return -1;
                    }
                    else if (left.Priority==right.Priority)
                    {
                        return 0;
                    }
                    else
                    {
                        return 1;
                    }
                });
            }

            //轮询所有模块
            for (int i = 0; i < _wrappers.Count; i++)
            {
                _wrappers[i].Singleton.OnUpdate();
            }
        }

        /// <summary>
        /// 获取单例
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T GetSingleton<T>() where T : class, ISingleton
        {
            System.Type type = typeof(T);
            for (int i = 0; i < _wrappers.Count; i++)
            {
                if (_wrappers[i].Singleton.GetType() == type)
                {
                    return _wrappers[i].Singleton as T;
                }
            }
            //MyDebug.LogError($"Not Found : {type} ");
            return null;
        }

        /// <summary>
        /// 是否存在单例
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static bool Contains<T>() where T : class, ISingleton
        {
            if (GetSingleton<T>() == null)
            {
                return false;
            }
            return true;
        }


        /// <summary>
        /// 创建单例
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="parma"></param>
        /// <param name="priority">运行时的优先级，优先级越大越早执行。如果没有设置优先级，那么会按照添加顺序执行</param>
        /// <returns></returns>
        public static T CreateSingleton<T>(object parma,int priority=0) where T : class, ISingleton {
            if (priority<0)
            {
                priority = 0;
                MyDebug.LogWarning($"优先级不能小于 0 ，已经重置为默认值 0");
            }

            if (Contains<T>())
            {
                MyDebug.LogWarning($"请不要重复创建该单例 {typeof(T)}");
            }

            //如果没有设置优先级
            if (priority==0)
            {
                int minPriority = GetMinPriority();
                priority = --minPriority;
            }

            T module = System.Activator.CreateInstance<T>();
            Wrapper wrapper = new Wrapper(module,priority);
            wrapper.Singleton.OnCreate(parma);
            _wrappers.Add(wrapper);
            _isDirty = true;
            return module;

        }

        /// <summary>
        /// 创建单例
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="priority">运行时的优先级，优先级越大越早执行。如果没有设置优先级，那么会按照添加顺序执行</param>
        /// <returns></returns>
        public static T CreateSingleton<T>(int priority = 0) where T : class, ISingleton {
            return CreateSingleton<T>(null,priority);
        }


        /// <summary>
        /// 开启一个协程
        /// </summary>
        public static Coroutine StartCoroutine(IEnumerator coroutine)
        {
            return _behaviour.StartCoroutine(coroutine);
        }
        public static Coroutine StartCoroutine(string methodName)
        {
            return _behaviour.StartCoroutine(methodName);
        }

        /// <summary>
        /// 停止一个协程
        /// </summary>
        public static void StopCoroutine(Coroutine coroutine)
        {
            _behaviour.StopCoroutine(coroutine);
        }
        public static void StopCoroutine(IEnumerator coroutine)
        {
            _behaviour.StopCoroutine(coroutine);
        }
        public static void StopCoroutine(string methodName)
        {
            _behaviour.StopCoroutine(methodName);
        }

        /// <summary>
        /// 停止所有协程
        /// </summary>
        public static void StopAllCoroutines()
        {
            _behaviour.StopAllCoroutines();
        }

        private static int GetMinPriority()
        {
            int minPriority = 0;
            for (int i = 0; i < _wrappers.Count; i++)
            {
                if (_wrappers[i].Priority < minPriority)
                    minPriority = _wrappers[i].Priority;
            }
            return minPriority; //小于等于零
        }

        private static void DestroyAll()
        {
            for (int i = 0; i < _wrappers.Count; i++)
            {
                _wrappers[i].Singleton.OnDestroy();
            }
            _wrappers.Clear();
        }

    }
}
